#include "jsz_translator.h"

// 全局变量定义
KeywordMapping* keyword_map = NULL;
int keyword_count = 0;
MessageMapping* message_map = NULL;
int message_count = 0;

/**
 * 从配置文件加载关键字映射
 */
bool load_keywords_from_config(const char* config_file) {
    FILE* file = fopen(config_file, "r");
    if (!file) {
        fprintf(stderr, get_message("ERROR_OPEN_CONFIG"), config_file);
        fprintf(stderr, "\n");
        return false;
    }

    // 分配初始内存
    keyword_map = malloc(MAX_KEYWORDS * sizeof(KeywordMapping));
    if (!keyword_map) {
        fprintf(stderr, "%s\n", get_message("ERROR_MEMORY_ALLOC"));
        fclose(file);
        return false;
    }

    char line[MAX_LINE_LENGTH];
    keyword_count = 0;

    while (fgets(line, sizeof(line), file) && keyword_count < MAX_KEYWORDS) {
        // 移除换行符
        line[strcspn(line, "\r\n")] = '\0';
        
        // 跳过空行和注释行
        if (line[0] == '\0' || line[0] == '#') {
            continue;
        }

        // 查找等号分隔符
        char* equals = strchr(line, '=');
        if (!equals) {
            continue; // 跳过格式不正确的行
        }

        // 分割JSZ关键字和JavaScript关键字
        *equals = '\0';
        char* jsz_keyword = line;
        char* js_keyword = equals + 1;

        // 去除前后空格
        while (*jsz_keyword == ' ' || *jsz_keyword == '\t') jsz_keyword++;
        while (*js_keyword == ' ' || *js_keyword == '\t') js_keyword++;
        
        char* end = jsz_keyword + strlen(jsz_keyword) - 1;
        while (end > jsz_keyword && (*end == ' ' || *end == '\t')) {
            *end = '\0';
            end--;
        }
        
        end = js_keyword + strlen(js_keyword) - 1;
        while (end > js_keyword && (*end == ' ' || *end == '\t')) {
            *end = '\0';
            end--;
        }

        // 检查关键字长度
        if (strlen(jsz_keyword) >= MAX_KEYWORD_LENGTH || 
            strlen(js_keyword) >= MAX_KEYWORD_LENGTH) {
            fprintf(stderr, get_message("WARN_KEYWORD_TOO_LONG"), jsz_keyword, js_keyword);
            fprintf(stderr, "\n");
            continue;
        }

        // 复制关键字到映射表
        strcpy(keyword_map[keyword_count].jsz_keyword, jsz_keyword);
        strcpy(keyword_map[keyword_count].js_keyword, js_keyword);
        keyword_count++;
    }

    fclose(file);
    
    if (keyword_count == 0) {
        fprintf(stderr, "%s\n", get_message("ERROR_NO_KEYWORDS"));
        free(keyword_map);
        keyword_map = NULL;
        return false;
    }

    printf(get_message("INFO_KEYWORDS_LOADED"), keyword_count);
    printf("\n");
    return true;
}

/**
 * 释放关键字映射内存
 */
void free_keywords(void) {
    if (keyword_map) {
        free(keyword_map);
        keyword_map = NULL;
        keyword_count = 0;
    }
}

/**
 * 从配置文件加载消息映射
 */
bool load_messages_from_config(const char* message_file) {
    FILE* file = fopen(message_file, "r");
    if (!file) {
        fprintf(stderr, "Error: Cannot open message file '%s'\n", message_file);
        return false;
    }

    // 分配初始内存
    message_map = malloc(MAX_MESSAGES * sizeof(MessageMapping));
    if (!message_map) {
        fprintf(stderr, "Error: Memory allocation failed\n");
        fclose(file);
        return false;
    }

    char line[MAX_LINE_LENGTH * 2]; // 消息可能比较长
    message_count = 0;

    while (fgets(line, sizeof(line), file) && message_count < MAX_MESSAGES) {
        // 移除换行符
        line[strcspn(line, "\r\n")] = '\0';
        
        // 跳过空行和注释行
        if (line[0] == '\0' || line[0] == '#') {
            continue;
        }

        // 查找等号分隔符
        char* equals = strchr(line, '=');
        if (!equals) {
            continue; // 跳过格式不正确的行
        }

        // 分割消息键和消息内容
        *equals = '\0';
        char* key = line;
        char* message = equals + 1;

        // 去除前后空格
        while (*key == ' ' || *key == '\t') key++;
        while (*message == ' ' || *message == '\t') message++;
        
        char* end = key + strlen(key) - 1;
        while (end > key && (*end == ' ' || *end == '\t')) {
            *end = '\0';
            end--;
        }
        
        end = message + strlen(message) - 1;
        while (end > message && (*end == ' ' || *end == '\t')) {
            *end = '\0';
            end--;
        }

        // 检查长度
        if (strlen(key) >= MAX_KEYWORD_LENGTH || 
            strlen(message) >= MAX_MESSAGE_LENGTH) {
            continue; // 跳过过长的消息
        }

        // 复制到映射表
        strcpy(message_map[message_count].key, key);
        strcpy(message_map[message_count].message, message);
        message_count++;
    }

    fclose(file);
    return message_count > 0;
}

/**
 * 释放消息映射内存
 */
void free_messages(void) {
    if (message_map) {
        free(message_map);
        message_map = NULL;
        message_count = 0;
    }
}

/**
 * 根据键获取消息
 */
const char* get_message(const char* key) {
    if (!message_map || !key) {
        return key; // 如果没有加载消息或键为空，返回原键
    }
    
    for (int i = 0; i < message_count; i++) {
        if (strcmp(message_map[i].key, key) == 0) {
            return message_map[i].message;
        }
    }
    
    return key; // 如果找不到，返回原键
}

/**
 * 读取文件内容到字符串
 */
char* read_file(const char* filename) {
    FILE* file = fopen(filename, "rb");
    if (!file) {
        fprintf(stderr, get_message("ERROR_OPEN_FILE"), filename);
        fprintf(stderr, "\n");
        return NULL;
    }

    // 获取文件大小
    fseek(file, 0, SEEK_END);
    long file_size = ftell(file);
    fseek(file, 0, SEEK_SET);

    if (file_size > MAX_FILE_SIZE) {
        fprintf(stderr, get_message("ERROR_FILE_TOO_LARGE"), filename, MAX_FILE_SIZE);
        fprintf(stderr, "\n");
        fclose(file);
        return NULL;
    }

    // 分配内存并读取文件
    char* content = malloc(file_size + 1);
    if (!content) {
        fprintf(stderr, "%s\n", get_message("ERROR_MEMORY_ALLOC"));
        fclose(file);
        return NULL;
    }

    size_t bytes_read = fread(content, 1, file_size, file);
    content[bytes_read] = '\0';
    
    fclose(file);
    return content;
}

/**
 * 将内容写入文件
 */
bool write_file(const char* filename, const char* content) {
    FILE* file = fopen(filename, "w");
    if (!file) {
        fprintf(stderr, get_message("ERROR_CREATE_FILE"), filename);
        fprintf(stderr, "\n");
        return false;
    }

    size_t content_length = strlen(content);
    size_t bytes_written = fwrite(content, 1, content_length, file);
    
    fclose(file);
    
    if (bytes_written != content_length) {
        fprintf(stderr, "%s\n", get_message("ERROR_WRITE_INCOMPLETE"));
        return false;
    }
    
    return true;
}

/**
 * 检查字符是否为关键字边界
 */
bool is_keyword_boundary(char c) {
    return c == ' ' || c == '\t' || c == '\n' || c == '\r' || 
           c == '(' || c == ')' || c == '{' || c == '}' || 
           c == '[' || c == ']' || c == ';' || c == ',' || 
           c == '.' || c == '+' || c == '-' || c == '*' || 
           c == '/' || c == '=' || c == '!' || c == '<' || 
           c == '>' || c == '&' || c == '|' || c == '^' || 
           c == '%' || c == '?' || c == ':' || c == '\0';
}

/**
 * 检查位置是否在字符串或注释中
 */
bool is_in_string_or_comment(const char* content, int position) {
    bool in_single_quote = false;
    bool in_double_quote = false;
    bool in_template_literal = false;
    bool in_template_expression = false;
    int template_brace_count = 0;
    bool in_single_comment = false;
    bool in_multi_comment = false;
    
    for (int i = 0; i < position; i++) {
        char c = content[i];
        char next_c = (i + 1 < position) ? content[i + 1] : '\0';
        
        // 处理转义字符
        if (c == '\\' && (in_single_quote || in_double_quote || (in_template_literal && !in_template_expression))) {
            i++; // 跳过下一个字符
            continue;
        }
        
        // 处理注释
        if (!in_single_quote && !in_double_quote && (!in_template_literal || in_template_expression)) {
            if (c == '/' && next_c == '/') {
                in_single_comment = true;
                i++; // 跳过第二个 /
                continue;
            }
            if (c == '/' && next_c == '*') {
                in_multi_comment = true;
                i++; // 跳过 *
                continue;
            }
            if (in_multi_comment && c == '*' && next_c == '/') {
                in_multi_comment = false;
                i++; // 跳过 /
                continue;
            }
        }
        
        // 处理换行（结束单行注释）
        if (c == '\n') {
            in_single_comment = false;
        }
        
        // 如果在注释中，跳过
        if (in_single_comment || in_multi_comment) {
            continue;
        }
        
        // 处理模板字符串中的表达式
        if (in_template_literal) {
            if (c == '$' && next_c == '{') {
                in_template_expression = true;
                template_brace_count = 1;
                i++; // 跳过 {
                continue;
            } else if (in_template_expression) {
                if (c == '{') {
                    template_brace_count++;
                } else if (c == '}') {
                    template_brace_count--;
                    if (template_brace_count == 0) {
                        in_template_expression = false;
                    }
                }
            }
        }
        
        // 处理字符串
        if (c == '\'' && !in_double_quote && !in_template_literal) {
            in_single_quote = !in_single_quote;
        } else if (c == '"' && !in_single_quote && !in_template_literal) {
            in_double_quote = !in_double_quote;
        } else if (c == '`' && !in_single_quote && !in_double_quote) {
            in_template_literal = !in_template_literal;
            if (!in_template_literal) {
                in_template_expression = false;
                template_brace_count = 0;
            }
        }
    }
    
    return in_single_quote || in_double_quote || 
           (in_template_literal && !in_template_expression) || 
           in_single_comment || in_multi_comment;
}

/**
 * 替换关键字
 */
char* replace_keywords(const char* content) {
    size_t content_len = strlen(content);
    size_t result_capacity = content_len * 2; // 预分配更多空间
    char* result = malloc(result_capacity);
    if (!result) {
        fprintf(stderr, "%s\n", get_message("ERROR_MEMORY_ALLOC"));
        return NULL;
    }
    
    size_t result_len = 0;
    size_t i = 0;
    
    while (i < content_len) {
        bool found_keyword = false;
        
        // 检查是否在字符串或注释中
        if (is_in_string_or_comment(content, i)) {
            // 在字符串或注释中，直接复制字符
            if (result_len >= result_capacity - 1) {
                result_capacity *= 2;
                result = realloc(result, result_capacity);
                if (!result) {
                    fprintf(stderr, "%s\n", get_message("ERROR_MEMORY_REALLOC"));
                    return NULL;
                }
            }
            result[result_len++] = content[i++];
            continue;
        }
        
        // 尝试匹配关键字
        for (int j = 0; j < keyword_count; j++) {
            size_t keyword_len = strlen(keyword_map[j].jsz_keyword);
            
            // 检查关键字是否匹配
            if (i + keyword_len <= content_len && 
                strncmp(content + i, keyword_map[j].jsz_keyword, keyword_len) == 0) {
                
                // 检查关键字边界
                bool valid_start = (i == 0) || is_keyword_boundary(content[i - 1]);
                bool valid_end = (i + keyword_len >= content_len) || 
                                is_keyword_boundary(content[i + keyword_len]);
                
                if (valid_start && valid_end) {
                    // 找到有效关键字，进行替换
                    size_t replacement_len = strlen(keyword_map[j].js_keyword);
                    
                    // 确保有足够空间
                    while (result_len + replacement_len >= result_capacity) {
                        result_capacity *= 2;
                        result = realloc(result, result_capacity);
                        if (!result) {
                            fprintf(stderr, "%s\n", get_message("ERROR_MEMORY_REALLOC"));
                            return NULL;
                        }
                    }
                    
                    // 复制替换的关键字
                    strcpy(result + result_len, keyword_map[j].js_keyword);
                    result_len += replacement_len;
                    i += keyword_len;
                    found_keyword = true;
                    break;
                }
            }
        }
        
        // 如果没有找到关键字，复制原字符
        if (!found_keyword) {
            if (result_len >= result_capacity - 1) {
                result_capacity *= 2;
                result = realloc(result, result_capacity);
                if (!result) {
                    fprintf(stderr, "%s\n", get_message("ERROR_MEMORY_REALLOC"));
                    return NULL;
                }
            }
            result[result_len++] = content[i++];
        }
    }
    
    result[result_len] = '\0';
    return result;
}

/**
 * 翻译JSZ内容到JavaScript
 */
char* translate_content(const char* content) {
    if (!content) {
        return NULL;
    }
    
    return replace_keywords(content);
}

/**
 * 主翻译函数
 */
bool translate_jsz_to_js(const char* input_file, const char* output_file) {
    printf(get_message("INFO_READING_FILE"), input_file);
    printf("\n");
    
    // 读取输入文件
    char* content = read_file(input_file);
    if (!content) {
        return false;
    }
    
    printf("%s\n", get_message("INFO_TRANSLATING"));
    
    // 翻译内容
    char* translated = translate_content(content);
    free(content);
    
    if (!translated) {
        return false;
    }
    
    printf(get_message("INFO_WRITING_FILE"), output_file);
    printf("\n");
    
    // 写入输出文件
    bool success = write_file(output_file, translated);
    free(translated);
    
    if (success) {
        printf("%s\n", get_message("INFO_TRANSLATION_COMPLETE"));
    }
    
    return success;
}

/**
 * 打印使用说明
 */
void print_usage(const char* program_name) {
    printf("%s\n", get_message("PROGRAM_TITLE"));
    printf(get_message("USAGE_FORMAT"), program_name);
    printf("\n\n");
    printf("%s\n", get_message("ARGUMENTS_TITLE"));
    printf("  %s\n", get_message("ARG_INPUT_FILE"));
    printf("  %s\n", get_message("ARG_OUTPUT_FILE"));
    printf("\n");
    printf("%s\n", get_message("OPTIONS_TITLE"));
    printf(get_message("OPT_CONFIG"), DEFAULT_CONFIG_FILENAME);
    printf("\n");
    printf("  %s\n", get_message("OPT_HELP"));
    printf("  %s\n", get_message("OPT_VERSION"));
    printf("\n");
    printf("%s\n", get_message("EXAMPLES_TITLE"));
    printf("  %s app.jsz\n", program_name);
    printf("  %s app.jsz app.js\n", program_name);
    printf("  %s -c custom.conf app.jsz\n", program_name);
}

/**
 * 打印版本信息
 */
void print_version(void) {
    printf("%s\n", get_message("VERSION_INFO"));
    printf("%s\n", get_message("VERSION_DESCRIPTION"));
    printf(get_message("VERSION_KEYWORDS"), keyword_count);
    printf("\n");
}